package com.wn.access.service.impl;
import java.time.LocalDateTime;
import java.util.Date;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wn.access.entity.TradeLog;
import com.wn.access.mapper.TradeLogMapper;
import com.wn.access.service.ITradeLogService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wn.common.model.bank.dto.BankCardAddDTO;
import com.wn.common.model.bank.dto.BankReqDto;
import com.wn.common.model.bank.dto.BaseResult;
import com.wn.common.model.bank.dto.SignatureDto;
import com.wn.common.model.borrow.BorrowSyncRecordVo;
import com.wn.common.utils.EncryptUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

/**
 * <p>
 * 托管系统交易记录表 服务实现类
 * </p>
 *
 * @author yellow docker
 * @since 2024-09-05
 */
@Service
@Slf4j
public class TradeLogServiceImpl extends ServiceImpl<TradeLogMapper, TradeLog> implements ITradeLogService {

    @Autowired
    private RestTemplate restTemplate;

    /**
     * 核心:
     *  1、记录日志
     *        创建一个trade-log 添加到数据库中
     *  2、给银行系统发送数据
     *        写法是固定的
     */

    @Override
    public SignatureDto proxyBindCardLog(BankCardAddDTO bankCardAddDTO) {

        TradeLog tradeLog = new TradeLog();

        tradeLog.setReqCode(bankCardAddDTO.getReqCode());
        //根据不同业务 给不同 的字段
        tradeLog.setReqType("USER_BIND_CARD");
        //给用户ID
        tradeLog.setObjectId(bankCardAddDTO.getUserId());

        //创建时间
        tradeLog.setCreateDate(LocalDateTime.now());

        //确认时间
        tradeLog.setConfirmDate(LocalDateTime.now());

        //银行返回数据  (数据同步 + 银行返回的数据 后面需要更新 )
        tradeLog.setSynchronizeStatus(0);
        tradeLog.setResponseData("");

        //添加日志
        save(tradeLog);

        //发送银行数据
        SignatureDto signatureDto = new SignatureDto();

        //银行给我们返回的数据
        //银行的url
        signatureDto.setBankUrl("http://localhost:5600/bank/user");
        //平台的编号
        signatureDto.setPlatformNo("SDDFP");
        // 银行返回的数据  (需要把银行返回的数据转成json字符串存储)
        try {
            /**
             *    User(name=aa,age=20) ===>  {"name":"aa","age":20}
             *      1、第三方的json包   hutool\fastjson （阿里巴巴提供的json工具类）
             *      2、springmvc 默认集成一个 jackson 工具类
             *
             *    ObjectMapper 这个是  jackson 提供的一个Java 转json的类
             *      writeValueAsString  ===> 对象转成json字符串
             *      readValue           ===> json字符串转成对象
             *
             */
            ObjectMapper objectMapper = new ObjectMapper();
            signatureDto.setReqData(new ObjectMapper().writeValueAsString(bankCardAddDTO));
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
        signatureDto.setReqCode(bankCardAddDTO.getReqCode());

        return signatureDto;
    }

    @Override
    public BaseResult syncBorrowRecord(BorrowSyncRecordVo borrowSyncRecordVo) {

        //1、记录日志
        TradeLog tradeLog = new TradeLog();

        //流水
        tradeLog.setReqCode(borrowSyncRecordVo.getReqCode());
        // 设置交易类型：SYNC表示数据同步操作
        tradeLog.setReqType("SYNC");
        //用户ID
        tradeLog.setObjectId(borrowSyncRecordVo.getUserId());
        //创建时间
        tradeLog.setCreateDate(LocalDateTime.now());
        //默认  银行系统 返回了数据后 status 要更新
        tradeLog.setSynchronizeStatus(0);
        tradeLog.setConfirmDate(LocalDateTime.now());
        //设置 银行返回的数据
        //tradeLog.setResponseData("");

        save(tradeLog);

        //2、给银行发送数据
        //url: http://localhost:5600/service?serviceName=SYNC_BORROW_RECORD&reqData = xxx
        //通过上面的方式发送数据给银行
        //2、远程调用托管系统
        //2.1 请求基础路径；作为完成路径的一部分
        String url = "http://localhost:5600/service";
        //2.2 发送数据给银行系统  看银行系统
        // url:  /service    serviceName= xxx服务(SYNC_BORROW_RECODE)
        // 请求数据:reqData
        // String url = "http://ip:5600/service?serviceName=SYNC_BORROW_RECODE&reqData=xxx";

        //2.3 请求数据 - 对象转换为JSON， 使用alibaba提供的fastjson工具类(银行托管也是使用fastjson)
        String str = JSON.toJSONString(borrowSyncRecordVo);
        //2.4 对象加密处理： str ---> Base64编码 ---> URL编码 ---> 目标str
        // str ---> Base64编码
        String base64Str = EncryptUtil.encodeUTF8StringBase64(str);
        // Base64编码 ---> URL编码
        String reqData = EncryptUtil.encodeURL(base64Str);
        // url:  /service    serviceName= xxx服务(SYNC_BORROW_RECODE)
        url = "http://localhost:5600/service?serviceName=SYNC_BORROW_RECORD&reqData=" + reqData;
        log.info("发送数据的url:{}",url);

        // 银行系统使用的是 @RestController 把对象都转成 json 字符串
        String respBody = restTemplate.getForObject(url, String.class);
        log.info("银行系统返回的数据:{}",respBody);
        //{"respData":{"respCode":"00000","respMsg":"成功","status":1,"requestNo":"REQ_208f14ff-b"}}
        BankReqDto bankReqDto = JSON.parseObject(respBody, BankReqDto.class);
        //拿到字符串解析
        //{"respCode":"00000","respMsg":"成功","status":1,"requestNo":"REQ_208f14ff-b"} ==> BaseResult
        BaseResult baseResult = JSON.parseObject(bankReqDto.getRespData(), BaseResult.class);
        log.info("银行系统返回的数据进行解析:{}",baseResult);
        String respMsg = baseResult.getRespMsg();
        if (respMsg.equals("成功")){
            //更新日志  更新  status、ResponseData
            update(
                    Wrappers.lambdaUpdate(TradeLog.class)
                            .set(TradeLog::getSynchronizeStatus,1)
                            .set(TradeLog::getResponseData,respBody)   // 银行响应的数据
                            .set(TradeLog::getConfirmDate,new Date())
                            .eq(TradeLog::getId,tradeLog.getId())
            );
        }
        return baseResult;

    }

}
